package com.wn.study.view

import android.view.View
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.ToastUtils
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import com.wn.common.base.BaseFragment
import com.wn.common.net.config.EYE_NAME
import com.wn.common.net.config.EYE_VALUE
import com.wn.study.R
import com.wn.study.StudyViewModel
import com.wn.study.databinding.FragmentStudyBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import libcore.net.okhttp.OkDomain
import javax.inject.Inject

/**
 * @Author: wn
 * @Date: 2023/6/8 15:46
 * @Description: 学习中心模块
 */
@AndroidEntryPoint
class StudyFragment : BaseFragment<FragmentStudyBinding>() {

  override fun getLayoutRes() = R.layout.fragment_study

  private val studyViewModel by viewModels<StudyViewModel>()

  @Inject
  lateinit var adapter: StudyAdapter

  @Inject
  lateinit var footerAdapter: FooterAdapter

  override fun initView() {
    super.initView()
    mBinding.apply {
      vm = studyViewModel
      // 上拉加载 --> 添加  底部 加载进度条  和 加载失败 重新加载按钮   (范围--加载中)
//      swipeRefresh.isEnabled = false
      rvStudy.adapter = adapter.withLoadStateFooter(footerAdapter)
      // TabLayout
      tlStudy.addOnTabSelectedListener(object : OnTabSelectedListener {
        /**
         * 被选的时候回调
         */
        override fun onTabSelected(tab: TabLayout.Tab?) {
          ToastUtils.showShort(tab!!.position)
        }

        /**
         * 未被选择时回调
         */
        override fun onTabUnselected(tab: TabLayout.Tab?) {
          ToastUtils.showShort("没被选择")
        }

        /**
         * 重新选择时回调--多次点击同一个 tab
         */
        override fun onTabReselected(tab: TabLayout.Tab?) {
          ToastUtils.showShort("重新选择时回调")
        }
      })
      // 下拉刷新-- Repository中 每次都需要 不同的 PagingSource 实例  那里无需 hilt
      adapter.apply {
        // 进度条颜色  背景色 setProgressBackgroundColorSchemeResource
        swipeRefresh.setColorSchemeResources(com.wn.common.R.color.colorPrimary)
        // 开启下拉刷新监听
        swipeRefresh.setOnRefreshListener {
          refresh()
        }
        // 下拉刷新 进度条取消
        lifecycleScope.launchWhenCreated {
          loadStateFlow.collectLatest {
            swipeRefresh.isRefreshing = it.refresh is LoadState.Loading
          }
        }

        // 初始化 加载状态监听器  与swipeRefresh自带的 进度重复  保留swipeRefresh的
        // (函数作用范围--初始化)
        addLoadStateListener {
          swPro.isVisible = it.refresh is LoadState.Loading
          when (it.refresh) {
            is LoadState.NotLoading -> {
              loadErrorView?.isVisible = it.append.endOfPaginationReached && itemCount < 1
              rvStudy.visibility = View.VISIBLE
            }
            // 这里添加一个  没有数据前的空白页
            is LoadState.Loading -> {
              rvStudy.visibility = View.INVISIBLE
            }
            is LoadState.Error -> {
              val state = it.refresh as LoadState.Error
              // 这里添加一个  错误页面 点击 Retry  初始化生效
              showLoadErrorView("Load Error: ${state.error.message}") {
                adapter.retry()
              }
            }
          }
        }
      }
    }
  }

  override fun initData() {
    super.initData()
    studyViewModel.apply {
      // 获取用户数据 + 观察
      getLiveUserInfo().observeKt {
        // 用户不存在 清空界面上的数据
        obUserInfo.set(it)
        // 骨架屏  rv 切换   未登录时
        mBinding.rvStudy.isVisible = it != null
        loadErrorView?.isVisible = it == null

        if (it == null) {
          showLoadErrorView("未登录  去登陆吧") {
            ARouter.getInstance().build("/login/login").navigation()
          }
          return@observeKt
        }
        lifecycleScope.launchWhenCreated {
//            repeatOnLifecycle(Lifecycle.State.STARTED){}
          // 用户存在 请求数据
          fetchData()
            .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
            .collect { data ->
              adapter.submitData(data)
            }
        }
      }
    }
  }

  /**
   * .addOkDomain(getBaseHost())// 初始化功能，baseurl为初始的主域名地址
   * 此方法为初始化 OkDomain 在前 -- 由 fetchAPi hilt 可以初始化 -- initData 中
   * 之后才可以  OkDomain.setDomain(EYE_NAME, EYE_VALUE) 在后 -- initConfig 中
   */
  override fun initConfig() {
    super.initConfig()
    // 初始化 加载 需要动态切换的 BaseUrl
    // 添加 开眼 域名
    OkDomain.setDomain(EYE_NAME, EYE_VALUE)
    // 关闭  Log
    OkDomain.debug = false
  }

  private var loadErrorView: View? = null

  /**
   * 初始化加载失败时 通过此方法显示提示界面给用户。
   * @param tip 界面中的提示信息
   * @param block 点击屏幕重新加载，回调处理。
   */
  private fun showLoadErrorView(tip: String, block: View.() -> Unit) {
    mBinding.apply {
      if (loadErrorView != null) {
        loadErrorView?.isVisible = true
      } else {
        val viewStub = stubErrorView.loadErrorView
        loadErrorView = viewStub.inflate()
      }
      val loadErrorText = loadErrorView?.findViewById<AppCompatTextView>(R.id.loadErrorText)
      loadErrorText?.text = tip
      loadErrorView?.setOnClickListener(block)
    }
  }
}